<?php

namespace App\Libraries;

use Parsedown;
use Symfony\Component\DomCrawler\Crawler;

class Markdown
{
    protected $markdown_parser;
    protected $converted_html;
    protected $toc_html;

    public function __construct()
    {
        $this->markdown_parser = new Parsedown();
    }

    /**
     * 转换 Markdown 格式为 HTML 格式
     *
     * @param  string $markdown
     * @return void
     */
    public function convertMarkdownToHtml($markdown)
    {
        $converted_html = $this->markdown_parser->setBreaksEnabled(true)->text($markdown);
        $this->converted_html = str_replace("<pre><code>", '<pre><code class="language-php">', $converted_html);
    }

    /**
     * 使用 h2 h3 标签生成目录
     *
     * @return void
     */
    public function generateToc()
    {
        if (empty($this->converted_html)) {
            return null;
        }

        $crawler = new Crawler();
        $crawler->addHtmlContent($this->converted_html, 'utf-8');

        $headers = $crawler->filter('h2,h3')->each(function (Crawler $node, $i) {

            $href = str_replace(' ', '-', $node->text());
            $node->getNode(0)->setAttribute('id', $href);

            return [
                'text'  => $node->text(),
                'href'  => $href,
                'level' => intval(substr($node->nodeName(), 1)),
            ];
        });

        $this->toc_html = $this->getTree($headers);
        $this->converted_html = $crawler->html();
    }

    /**
     * 生成目录树
     *
     * @param  array  $items
     * @param  integer  $level
     * @param  integer &$index
     * @return string
     */
    protected function getTree($items, $level = 2, &$index = 0)
    {
        $count = count($items);
        $html = '<ul class="nav">';

        while ($index < $count) {
            if ($items[$index]['level'] === $level) {
                $html .= '<li><a href="#' . $items[$index]['href'] . '">' . $items[$index]['text'] . '</a></li>';
                $index++;
            } elseif ($items[$index]['level'] > $level) {
                $html = substr_replace($html, $this->getTree($items, $items[$index]['level'], $index), -5, 0);
            } else {
                break;
            }
        }

        $html .= '</ul>';

        return $html;
    }

    /**
     * 获取转换后的 HTML
     *
     * @return string
     */
    public function getHtml()
    {
        return $this->converted_html;
    }

    /**
     * 获取目录
     *
     * @return string
     */
    public function getToc()
    {
        return $this->toc_html;
    }
}
